package com.marktotop.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.marktotop.entity.system.Menu;
import com.marktotop.entity.system.Role;
import com.marktotop.entity.system.RoleMenu;
import com.marktotop.enums.RoleStatusEnum;
import com.marktotop.error.SystemCodeEnum;
import com.marktotop.error.SystemException;
import com.marktotop.mapper.MenuMapper;
import com.marktotop.mapper.RoleMapper;
import com.marktotop.mapper.RoleMenuMapper;
import com.marktotop.mapper.UserMapper;
import com.marktotop.response.ResultBean;
import com.marktotop.response.ResultCode;
import com.marktotop.service.IRoleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.marktotop.vo.system.RoleVO;
import com.marktotop.vo.system.UserVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.validation.constraints.NotBlank;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 角色表 服务实现类
 * </p>
 *
 * @author MarkToTop
 * @since 2021-07-12
 */
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IRoleService {

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private RoleMenuMapper roleMenuMapper;

    @Autowired
    private MenuMapper menuMapper;


    /**
     * 角色分配权限
     *
     * @param id
     * @param mids
     * @return
     * @throws SystemException
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean authority(Long id, Long[] mids) throws SystemException {
        Role role = roleMapper.selectById(id);
        if(role==null){
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"该角色不存在");
        }
        //先删除原来的权限
        roleMenuMapper.delete(new QueryWrapper<RoleMenu>().eq("role_id", id));

        //增加现在分配的角色
        if(mids.length > 0) {
            for (Long mid : mids) {
                Menu menu = menuMapper.selectById(mid);
                if (menu == null) {
                    throw new SystemException(SystemCodeEnum.PARAMETER_ERROR, "menuId=" + mid + ",菜单权限不存在!");
                } else {
                    RoleMenu roleMenu = new RoleMenu();
                    roleMenu.setRoleId(id);
                    roleMenu.setMenuId(mid);
                    roleMenuMapper.insert(roleMenu);
                }
            }
        }
        return true;
    }



    /**
     * 获取角色已有权限id
     * @param id
     * @return
     */
    @Override
    public List<Long> findMenuIdsByRoleId(Long id) throws SystemException {
        Role role = roleMapper.selectById(id);
        if(role == null){
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"该角色不存在...请查证！");
        }
        List<Long> ids=new ArrayList<>();
        List<RoleMenu> roleMenus = roleMenuMapper.selectList(new QueryWrapper<RoleMenu>().eq("role_id", id));
        if(!CollectionUtils.isEmpty(roleMenus)){
            for (RoleMenu roleMenu : roleMenus) {
                ids.add(roleMenu.getMenuId());
            }
        }
        return ids;
    }

    /**
     * 分页展示所有角色
     *
     * @param pageNum
     * @param pageSize
     * @param roleVO
     * @return
     */
    @Override
    public ResultBean findRoleList(Integer pageNum, Integer pageSize, RoleVO roleVO) {
        // 开启分页
        Page<RoleVO> page = new Page<>(pageNum,pageSize);
        IPage<RoleVO> rolesByPage = roleMapper.getRolesByPage(page,roleVO);
        if (rolesByPage.getRecords().isEmpty()){
            return ResultBean.result(ResultCode.NON_RESULT);
        }
        return ResultBean.ok().message("获取全部角色信息成功！")
                .data("total",rolesByPage.getTotal())
                .data("roleList",rolesByPage.getRecords());
    }

    /**
     * 保存新的角色信息
     *
     * @param roleVO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveRole(RoleVO roleVO) throws SystemException {
        @NotBlank(message = "角色名必填") String roleName = roleVO.getRoleName();
        Integer count = roleMapper.selectCount(new QueryWrapper<Role>().eq("role_name", roleName));

        if(count != 0){
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"该角色名已被占用");
        }
        Role role = new Role();
        BeanUtils.copyProperties(roleVO,role);
        role.setCreateTime(new Date());
        role.setModifiedTime(new Date());
        // 默认启用添加的角色
        role.setStatus(RoleStatusEnum.AVAILABLE.getStatusCode());
        roleMapper.insert(role);
    }


    /**
     * 编辑角色信息
     *
     * @param id
     * @return
     */
    @Override
    public RoleVO editRole(Long id) throws SystemException {
        Role role = roleMapper.selectById(id);
        if(null == role){
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"编辑的角色不存在...");
        }
        RoleVO roleVO = new RoleVO();
        BeanUtils.copyProperties(role,roleVO);
        return roleVO;
    }

    /**
     * 更新角色信息
     *
     * @param id
     * @param roleVO
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateRole(Long id, RoleVO roleVO) throws SystemException {
        @NotBlank(message = "角色名必填") String roleName = roleVO.getRoleName();
        Role dbRole = roleMapper.selectById(id);
        if(dbRole==null){
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"要更新的角色不存在");
        }
        List<Role> roles = roleMapper.selectList(new QueryWrapper<Role>().eq("role_name", roleName));
        if(!CollectionUtils.isEmpty(roles)){
            Role role = roles.get(0);
            if(!role.getId().equals(id)){
                throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"该角色名已被占用");
            }
        }
        Role role = new Role();
        BeanUtils.copyProperties(roleVO,role);
        role.setModifiedTime(new Date());
        roleMapper.updateById(role);
    }

    /**
     * 更新角色状态
     *
     * @param id
     * @param status
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateStatus(Long id, Boolean status) throws SystemException {
        Role role = roleMapper.selectById(id);
        if(role==null){
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"操作的角色不存在!");
        }
        Role t = new Role();
        t.setId(id);
        t.setStatus(status ? RoleStatusEnum.AVAILABLE.getStatusCode():
                RoleStatusEnum.DISABLE.getStatusCode());
        roleMapper.updateById(t);
    }
}
